สำรวจ File System Access API อันทรงพลัง ที่ช่วยให้เว็บแอปอ่าน เขียน และจัดการไฟล์ในเครื่องได้อย่างปลอดภัย คู่มือฉบับสมบูรณ์สำหรับนักพัฒนาทั่วโลก
ปลดล็อกระบบไฟล์ในเครื่อง: เจาะลึก Frontend File System Access API
เป็นเวลาหลายทศวรรษที่เบราว์เซอร์เป็นสภาพแวดล้อมแบบ sandboxed ซึ่งเป็นพื้นที่ที่ปลอดภัยแต่ก็มีข้อจำกัดโดยพื้นฐาน หนึ่งในขอบเขตที่เข้มงวดที่สุดคือระบบไฟล์ในเครื่อง เว็บแอปพลิเคชันสามารถขอให้คุณอัปโหลดไฟล์หรือแจ้งให้คุณดาวน์โหลดไฟล์ได้ แต่แนวคิดของโปรแกรมแก้ไขข้อความบนเว็บที่สามารถเปิดไฟล์ ให้คุณแก้ไข และบันทึกกลับไปยังตำแหน่งเดิมนั้นเป็นเรื่องเพ้อฝัน ข้อจำกัดนี้เป็นเหตุผลหลักที่ทำให้แอปพลิเคชันเดสก์ท็อปแบบเนทีฟยังคงความได้เปรียบสำหรับงานที่ต้องมีการจัดการไฟล์อย่างหนักหน่วง เช่น การตัดต่อวิดีโอ การพัฒนาซอฟต์แวร์ และการออกแบบกราฟิก
กระบวนทัศน์นั้นกำลังเปลี่ยนแปลงไป File System Access API ซึ่งเดิมเรียกว่า Native File System API ได้ทลายกำแพงที่ยืนหยัดมานานนี้ลง API นี้มอบกลไกที่เป็นมาตรฐาน ปลอดภัย และทรงพลังให้นักพัฒนาเว็บสามารถอ่าน เขียน และจัดการไฟล์และไดเรกทอรีบนเครื่องของผู้ใช้ได้ นี่ไม่ใช่ช่องโหว่ด้านความปลอดภัย แต่เป็นวิวัฒนาการที่สร้างขึ้นอย่างรอบคอบ โดยให้ผู้ใช้เป็นผู้ควบคุมอย่างสมบูรณ์ผ่านการอนุญาตที่ชัดเจน
API นี้เป็นรากฐานที่สำคัญสำหรับ Progressive Web Applications (PWAs) รุ่นต่อไป โดยมอบความสามารถที่เคยเป็นเอกสิทธิ์ของซอฟต์แวร์เนทีฟ ลองจินตนาการถึง IDE บนเว็บที่สามารถจัดการโฟลเดอร์โปรเจกต์ในเครื่อง โปรแกรมแก้ไขรูปภาพที่ทำงานโดยตรงกับรูปภาพความละเอียดสูงของคุณโดยไม่ต้องอัปโหลด หรือแอปจดบันทึกที่บันทึกไฟล์ markdown ลงในโฟลเดอร์เอกสารของคุณโดยตรง นี่คืออนาคตที่ File System Access API ทำให้เป็นจริงได้
ในคู่มือฉบับสมบูรณ์นี้ เราจะสำรวจทุกแง่มุมของ API ที่จะมาเปลี่ยนแปลงวงการนี้ เราจะเจาะลึกถึงประวัติศาสตร์ ทำความเข้าใจหลักการความปลอดภัยหลัก เดินผ่านตัวอย่างโค้ดที่ใช้งานได้จริงสำหรับการอ่าน เขียน และการจัดการไดเรกทอรี และหารือเกี่ยวกับเทคนิคขั้นสูงและกรณีการใช้งานจริงที่จะเป็นแรงบันดาลใจสำหรับโปรเจกต์ต่อไปของคุณ
วิวัฒนาการของการจัดการไฟล์บนเว็บ
เพื่อให้เข้าใจถึงความสำคัญของ File System Access API อย่างแท้จริง การย้อนกลับไปดูประวัติศาสตร์ว่าเบราว์เซอร์จัดการกับไฟล์ในเครื่องอย่างไรจะเป็นประโยชน์ การเดินทางครั้งนี้เป็นการทำซ้ำอย่างค่อยเป็นค่อยไปโดยคำนึงถึงความปลอดภัยเป็นหลัก
แนวทางดั้งเดิม: Inputs และ Anchors
วิธีการดั้งเดิมในการโต้ตอบกับไฟล์นั้นเรียบง่ายและถูกควบคุมอย่างเข้มงวด:
- การอ่านไฟล์: อิลิเมนต์
<input type="file">เป็นเครื่องมือหลักสำหรับการอัปโหลดไฟล์มานานหลายปี เมื่อผู้ใช้เลือกไฟล์ (หรือหลายไฟล์ด้วยแอตทริบิวต์multiple) แอปพลิเคชันจะได้รับอ็อบเจ็กต์FileListจากนั้นนักพัฒนาสามารถใช้FileReaderAPI เพื่ออ่านเนื้อหาของไฟล์เหล่านี้เข้าไปในหน่วยความจำในรูปแบบสตริง, ArrayBuffer หรือ data URL อย่างไรก็ตาม แอปพลิเคชันจะไม่เคยรู้เส้นทางดั้งเดิมของไฟล์และไม่มีทางที่จะเขียนกลับไปยังไฟล์นั้นได้ ทุกการดำเนินการ 'บันทึก' คือการ 'ดาวน์โหลด' - การบันทึกไฟล์: การบันทึกยิ่งเป็นทางอ้อมมากขึ้นไปอีก เทคนิคทั่วไปคือการสร้างแท็ก
<a>(anchor) กำหนดแอตทริบิวต์hrefเป็น data URI หรือ Blob URL เพิ่มแอตทริบิวต์downloadพร้อมชื่อไฟล์ที่แนะนำ และคลิกมันโดยใช้โปรแกรม การกระทำนี้จะแสดงกล่องโต้ตอบ 'Save As...' ให้กับผู้ใช้ ซึ่งโดยทั่วไปจะเริ่มต้นที่โฟลเดอร์ 'Downloads' ของพวกเขา ผู้ใช้ต้องนำทางไปยังตำแหน่งที่ถูกต้องด้วยตนเองหากต้องการเขียนทับไฟล์ที่มีอยู่
ข้อจำกัดของวิธีการเก่า
แม้ว่าจะใช้งานได้ แต่โมเดลคลาสสิกนี้ก็มีข้อจำกัดที่สำคัญสำหรับการสร้างแอปพลิเคชันที่ซับซ้อน:
- การโต้ตอบแบบไร้สถานะ (Stateless Interaction): การเชื่อมต่อกับไฟล์จะหายไปทันทีหลังจากที่อ่านเสร็จ หากผู้ใช้แก้ไขเอกสารและต้องการบันทึก แอปพลิเคชันจะไม่สามารถเขียนทับไฟล์ต้นฉบับได้ พวกเขาต้องดาวน์โหลดสำเนาใหม่ ซึ่งมักจะมีชื่อที่แก้ไขแล้ว (เช่น 'document(1).txt') นำไปสู่ความยุ่งเหยิงของไฟล์และประสบการณ์ผู้ใช้ที่สับสน
- ไม่มีการเข้าถึงไดเรกทอรี: ไม่มีแนวคิดเรื่องโฟลเดอร์ แอปพลิเคชันไม่สามารถขอให้ผู้ใช้เปิดไดเรกทอรีโปรเจกต์ทั้งหมดเพื่อทำงานกับเนื้อหาภายในได้ ซึ่งเป็นข้อกำหนดพื้นฐานสำหรับ IDE หรือโปรแกรมแก้ไขโค้ดบนเว็บ
- ความยุ่งยากของผู้ใช้: วงจรที่ต้องทำซ้ำๆ ของ 'Open...' -> 'Edit' -> 'Save As...' -> 'Navigate...' -> 'Overwrite?' นั้นยุ่งยากและไม่มีประสิทธิภาพเมื่อเทียบกับประสบการณ์ง่ายๆ อย่าง 'Ctrl + S' หรือ 'Cmd + S' ในแอปพลิเคชันเนทีฟ
ข้อจำกัดเหล่านี้ทำให้เว็บแอปเป็นเพียงผู้บริโภคและผู้สร้างไฟล์ชั่วคราว ไม่ใช่โปรแกรมแก้ไขข้อมูลในเครื่องของผู้ใช้ที่คงอยู่ถาวร File System Access API ถูกสร้างขึ้นมาเพื่อแก้ไขข้อบกพร่องเหล่านี้โดยตรง
ขอแนะนำ File System Access API
File System Access API เป็นมาตรฐานเว็บสมัยใหม่ที่ให้สะพานเชื่อมโดยตรงไปยังระบบไฟล์ในเครื่องของผู้ใช้ แม้ว่าจะต้องผ่านการอนุญาตก็ตาม ช่วยให้นักพัฒนาสามารถสร้างประสบการณ์ที่สมบูรณ์เทียบเท่าเดสก์ท็อป โดยที่ไฟล์และไดเรกทอรีได้รับการปฏิบัติเหมือนเป็นส่วนสำคัญอันดับแรก
แนวคิดหลักและคำศัพท์
การทำความเข้าใจ API เริ่มต้นด้วยอ็อบเจ็กต์หลัก ซึ่งทำหน้าที่เป็นตัวจัดการ (handles) หรือการอ้างอิงถึงรายการต่างๆ ในระบบไฟล์
FileSystemHandle: นี่คืออินเทอร์เฟซพื้นฐานสำหรับทั้งไฟล์และไดเรกทอรี มันแสดงถึงหนึ่งรายการในระบบไฟล์และมีคุณสมบัติเช่นnameและkind('file' หรือ 'directory')FileSystemFileHandle: อินเทอร์เฟซนี้แสดงถึงไฟล์ มันสืบทอดจากFileSystemHandleและมีเมธอดสำหรับโต้ตอบกับเนื้อหาของไฟล์ เช่นgetFile()เพื่อรับอ็อบเจ็กต์Fileมาตรฐาน (สำหรับอ่านข้อมูลเมตาหรือเนื้อหา) และcreateWritable()เพื่อรับสตรีมสำหรับเขียนข้อมูลFileSystemDirectoryHandle: สิ่งนี้แสดงถึงไดเรกทอรี ช่วยให้คุณสามารถแสดงรายการเนื้อหาของไดเรกทอรีหรือรับ handle ไปยังไฟล์หรือไดเรกทอรีย่อยที่ระบุภายในนั้นได้โดยใช้เมธอดเช่นgetFileHandle()และgetDirectoryHandle()นอกจากนี้ยังมี asynchronous iterators เพื่อวนซ้ำผ่านรายการต่างๆFileSystemWritableFileStream: นี่คืออินเทอร์เฟซแบบสตรีมที่ทรงพลังสำหรับเขียนข้อมูลลงในไฟล์ ช่วยให้คุณสามารถเขียนสตริง, Blobs หรือ Buffers ได้อย่างมีประสิทธิภาพ และมีเมธอดสำหรับเลื่อนไปยังตำแหน่งที่ระบุหรือตัดทอนไฟล์ คุณต้องเรียกใช้เมธอดclose()ของมันเพื่อให้แน่ใจว่าการเปลี่ยนแปลงจะถูกเขียนลงดิสก์
โมเดลความปลอดภัย: เน้นผู้ใช้เป็นศูนย์กลางและปลอดภัย
การอนุญาตให้เว็บไซต์เข้าถึงระบบไฟล์ของคุณโดยตรงเป็นข้อพิจารณาด้านความปลอดภัยที่สำคัญ ผู้ออกแบบ API นี้ได้สร้างโมเดลความปลอดภัยที่แข็งแกร่งและอิงตามการอนุญาต ซึ่งให้ความสำคัญกับความยินยอมและการควบคุมของผู้ใช้เป็นอันดับแรก
- การกระทำที่เริ่มต้นโดยผู้ใช้: แอปพลิเคชันไม่สามารถเปิดตัวเลือกไฟล์ขึ้นมาเองได้ การเข้าถึงต้องเริ่มต้นจากการกระทำของผู้ใช้โดยตรง เช่น การคลิกปุ่ม ซึ่งจะป้องกันไม่ให้สคริปต์ที่เป็นอันตรายสแกนระบบไฟล์ของคุณอย่างเงียบๆ
- ตัวเลือกไฟล์คือประตูทางเข้า: จุดเริ่มต้นของ API คือเมธอดตัวเลือกไฟล์:
window.showOpenFilePicker(),window.showSaveFilePicker()และwindow.showDirectoryPicker()เมธอดเหล่านี้จะแสดง UI การเลือกไฟล์/ไดเรกทอรีของเบราว์เซอร์ การเลือกของผู้ใช้ถือเป็นการให้สิทธิ์อย่างชัดเจนสำหรับรายการนั้นๆ - การแจ้งเตือนเพื่อขอสิทธิ์: หลังจากได้รับ handle แล้ว เบราว์เซอร์อาจแจ้งให้ผู้ใช้ให้สิทธิ์ 'อ่าน' หรือ 'อ่าน-เขียน' สำหรับ handle นั้น ผู้ใช้ต้องอนุมัติการแจ้งเตือนนี้ก่อนที่แอปพลิเคชันจะดำเนินการต่อได้
- การคงอยู่ของสิทธิ์: เพื่อประสบการณ์ผู้ใช้ที่ดีขึ้น เบราว์เซอร์สามารถคงสิทธิ์เหล่านี้ไว้สำหรับ origin (เว็บไซต์) ที่กำหนดได้ ซึ่งหมายความว่าหลังจากผู้ใช้ให้สิทธิ์เข้าถึงไฟล์ครั้งหนึ่งแล้ว พวกเขาจะไม่ถูกถามอีกในเซสชันเดียวกันหรือแม้แต่ในการเข้าชมครั้งต่อไป สถานะสิทธิ์สามารถตรวจสอบได้ด้วย
handle.queryPermission()และขอใหม่ได้ด้วยhandle.requestPermission()ผู้ใช้สามารถเพิกถอนสิทธิ์เหล่านี้ได้ตลอดเวลาผ่านการตั้งค่าของเบราว์เซอร์ - เฉพาะใน Secure Contexts เท่านั้น: เช่นเดียวกับเว็บ API สมัยใหม่หลายๆ ตัว File System Access API จะใช้งานได้เฉพาะใน secure contexts เท่านั้น ซึ่งหมายความว่าเว็บไซต์ของคุณต้องให้บริการผ่าน HTTPS หรือจาก localhost
แนวทางหลายชั้นนี้ทำให้มั่นใจได้ว่าผู้ใช้จะรับรู้และควบคุมได้เสมอ เป็นการสร้างสมดุลระหว่างความสามารถใหม่ที่ทรงพลังและความปลอดภัยที่ไม่ลดหย่อน
การนำไปใช้งานจริง: คำแนะนำทีละขั้นตอน
เรามาเปลี่ยนจากทฤษฎีสู่การปฏิบัติกัน นี่คือวิธีที่คุณสามารถเริ่มใช้ File System Access API ในเว็บแอปพลิเคชันของคุณได้ เมธอด API ทั้งหมดเป็นแบบอะซิงโครนัสและคืนค่า Promises ดังนั้นเราจะใช้ синтаксис async/await ที่ทันสมัยเพื่อให้โค้ดสะอาดขึ้น
การตรวจสอบการรองรับของเบราว์เซอร์
ก่อนที่จะใช้ API คุณต้องตรวจสอบว่าเบราว์เซอร์ของผู้ใช้รองรับหรือไม่ การตรวจสอบคุณสมบัติอย่างง่ายก็เพียงพอแล้ว
if ('showOpenFilePicker' in window) {
console.log('Great! The File System Access API is supported.');
} else {
console.log('Sorry, this browser does not support the API.');
// Provide a fallback to <input type="file">
}
การอ่านไฟล์
การอ่านไฟล์ในเครื่องเป็นจุดเริ่มต้นที่พบบ่อย กระบวนการนี้เกี่ยวข้องกับการแสดงตัวเลือกไฟล์ การรับ file handle แล้วจึงอ่านเนื้อหาของไฟล์
const openFileButton = document.getElementById('open-file-btn');
openFileButton.addEventListener('click', async () => {
try {
// The showOpenFilePicker() method returns an array of handles,
// but we are only interested in the first one for this example.
const [fileHandle] = await window.showOpenFilePicker();
// Get the File object from the handle.
const file = await fileHandle.getFile();
// Read the file content as text.
const content = await file.text();
// Use the content (e.g., display it in a textarea).
document.getElementById('editor').value = content;
} catch (err) {
// Handle errors, such as the user canceling the picker.
console.error('Error opening file:', err);
}
});
ในตัวอย่างนี้ window.showOpenFilePicker() คืนค่า promise ที่จะ resolve ด้วยอาร์เรย์ของอ็อบเจ็กต์ FileSystemFileHandle เราทำการ destructure อิลิเมนต์แรกเข้าไปในตัวแปร fileHandle ของเรา จากนั้น fileHandle.getFile() จะให้อ็อบเจ็กต์ File มาตรฐาน ซึ่งมีเมธอดที่คุ้นเคยเช่น .text(), .arrayBuffer() และ .stream()
การเขียนลงไฟล์
การเขียนคือส่วนที่ API นี้โดดเด่นอย่างแท้จริง เนื่องจากช่วยให้สามารถบันทึกไฟล์ใหม่และเขียนทับไฟล์ที่มีอยู่ได้อย่างราบรื่น
การบันทึกการเปลี่ยนแปลงไปยังไฟล์ที่มีอยู่
มาขยายตัวอย่างก่อนหน้านี้ของเรา เราจำเป็นต้องเก็บ fileHandle ไว้เพื่อที่เราจะสามารถใช้ในภายหลังเพื่อบันทึกการเปลี่ยนแปลง
let currentFileHandle;
// ... inside the 'openFileButton' click listener ...
// After getting the handle from showOpenFilePicker:
currentFileHandle = fileHandle;
// --- Now, set up the save button ---
const saveFileButton = document.getElementById('save-file-btn');
saveFileButton.addEventListener('click', async () => {
if (!currentFileHandle) {
alert('Please open a file first!');
return;
}
try {
// Create a FileSystemWritableFileStream to write to.
const writable = await currentFileHandle.createWritable();
// Get the content from our editor.
const content = document.getElementById('editor').value;
// Write the content to the stream.
await writable.write(content);
// Close the file and write the contents to disk.
// This is a crucial step!
await writable.close();
alert('File saved successfully!');
} catch (err) {
console.error('Error saving file:', err);
}
});
ขั้นตอนสำคัญคือ createWritable() ซึ่งเตรียมไฟล์สำหรับการเขียน, write() ซึ่งส่งข้อมูล และ close() ที่สำคัญอย่างยิ่ง ซึ่งจะสิ้นสุดการดำเนินการและคอมมิตการเปลี่ยนแปลงลงดิสก์
การบันทึกไฟล์ใหม่ ('Save As')
ในการบันทึกไฟล์ใหม่ คุณใช้ window.showSaveFilePicker() ซึ่งจะแสดงกล่องโต้ตอบ 'Save As' และคืนค่า FileSystemFileHandle ใหม่สำหรับตำแหน่งที่เลือก
const saveAsButton = document.getElementById('save-as-btn');
saveAsButton.addEventListener('click', async () => {
try {
const newFileHandle = await window.showSaveFilePicker({
suggestedName: 'untitled.txt',
types: [{
description: 'Text Files',
accept: {
'text/plain': ['.txt'],
},
}],
});
// Now we have a handle, we can use the same writing logic as before.
const writable = await newFileHandle.createWritable();
const content = document.getElementById('editor').value;
await writable.write(content);
await writable.close();
// Optionally, update our current handle to this new file.
currentFileHandle = newFileHandle;
alert('File saved to a new location!');
} catch (err) {
console.error('Error saving new file:', err);
}
});
การทำงานกับไดเรกทอรี
ความสามารถในการทำงานกับไดเรกทอรีทั้งหมดปลดล็อกกรณีการใช้งานที่ทรงพลัง เช่น IDE บนเว็บ
ขั้นแรก เราให้ผู้ใช้เลือกไดเรกทอรี:
const openDirButton = document.getElementById('open-dir-btn');
openDirButton.addEventListener('click', async () => {
try {
const dirHandle = await window.showDirectoryPicker();
// Now we can process the directory's contents.
await processDirectory(dirHandle);
} catch (err) {
console.error('Error opening directory:', err);
}
});
เมื่อคุณมี FileSystemDirectoryHandle แล้ว คุณสามารถวนซ้ำผ่านเนื้อหาของมันได้โดยใช้ลูป async for...of ฟังก์ชันต่อไปนี้จะแสดงรายการไฟล์และไดเรกทอรีย่อยทั้งหมดแบบเรียกซ้ำ
async function processDirectory(dirHandle) {
const fileListElement = document.getElementById('file-list');
fileListElement.innerHTML = ''; // Clear previous list
for await (const entry of dirHandle.values()) {
const listItem = document.createElement('li');
// The 'kind' property is either 'file' or 'directory'
listItem.textContent = `[${entry.kind}] ${entry.name}`;
fileListElement.appendChild(listItem);
if (entry.kind === 'directory') {
// This shows a simple recursive call is possible,
// though a full UI would handle nesting differently.
console.log(`Found subdirectory: ${entry.name}`);
}
}
}
การสร้างไฟล์และไดเรกทอรีใหม่
คุณยังสามารถสร้างไฟล์และไดเรกทอรีย่อยใหม่โดยใช้โปรแกรมภายในไดเรกทอรีที่คุณมีสิทธิ์เข้าถึงได้ ทำได้โดยการส่งออปชัน { create: true } ไปยังเมธอด getFileHandle() หรือ getDirectoryHandle()
async function createNewFile(dirHandle, fileName) {
try {
// Get a handle to a new file, creating it if it doesn't exist.
const newFileHandle = await dirHandle.getFileHandle(fileName, { create: true });
console.log(`Created or got handle for file: ${newFileHandle.name}`);
// You can now write to this handle.
} catch (err) {
console.error('Error creating file:', err);
}
}
async function createNewFolder(dirHandle, folderName) {
try {
// Get a handle to a new directory, creating it if it doesn't exist.
const newDirHandle = await dirHandle.getDirectoryHandle(folderName, { create: true });
console.log(`Created or got handle for directory: ${newDirHandle.name}`);
} catch (err) {
console.error('Error creating directory:', err);
}
}
แนวคิดขั้นสูงและกรณีการใช้งาน
เมื่อคุณเชี่ยวชาญพื้นฐานแล้ว คุณสามารถสำรวจคุณสมบัติขั้นสูงเพิ่มเติมเพื่อสร้างประสบการณ์ผู้ใช้ที่ราบรื่นอย่างแท้จริง
การคงอยู่ของข้อมูลด้วย IndexedDB
ความท้าทายที่สำคัญคืออ็อบเจ็กต์ FileSystemHandle จะไม่ถูกเก็บรักษาไว้เมื่อผู้ใช้รีเฟรชหน้าเว็บ เพื่อแก้ปัญหานี้ คุณสามารถเก็บ handle ไว้ใน IndexedDB ซึ่งเป็นฐานข้อมูลฝั่งไคลเอ็นต์ของเบราว์เซอร์ สิ่งนี้ช่วยให้แอปพลิเคชันของคุณจดจำไฟล์และโฟลเดอร์ที่ผู้ใช้กำลังทำงานอยู่ข้ามเซสชันได้
การจัดเก็บ handle นั้นง่ายเหมือนกับการใส่มันลงใน object store ของ IndexedDB การดึงข้อมูลกลับมาก็ง่ายเช่นกัน อย่างไรก็ตาม สิทธิ์ จะไม่ถูกเก็บไว้กับ handle เมื่อแอปของคุณโหลดใหม่และดึง handle จาก IndexedDB คุณต้องตรวจสอบก่อนว่าคุณยังมีสิทธิ์อยู่หรือไม่และขอใหม่หากจำเป็น
// Function to retrieve a stored handle
async function getHandleFromDB(key) {
// (Code for opening IndexedDB and getting the handle)
const handle = await getFromDB(key);
if (!handle) return null;
// Check if we still have permission.
if (await handle.queryPermission({ mode: 'readwrite' }) === 'granted') {
return handle; // Permission already granted.
}
// If not, we must request permission again.
if (await handle.requestPermission({ mode: 'readwrite' }) === 'granted') {
return handle; // Permission was granted by the user.
}
// Permission was denied.
return null;
}
รูปแบบนี้ช่วยให้คุณสร้างคุณสมบัติ 'ไฟล์ล่าสุด' หรือ 'เปิดโปรเจกต์ล่าสุด' ที่ให้ความรู้สึกเหมือนแอปพลิเคชันเนทีฟ
การผสานรวมกับ Drag and Drop
API นี้ผสานรวมเข้ากับ Drag and Drop API ของเบราว์เซอร์ได้อย่างสวยงาม ผู้ใช้สามารถลากไฟล์หรือโฟลเดอร์จากเดสก์ท็อปและวางลงบนเว็บแอปพลิเคชันของคุณเพื่อให้สิทธิ์การเข้าถึง ทำได้ผ่านเมธอด DataTransferItem.getAsFileSystemHandle()
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('dragover', (event) => {
event.preventDefault(); // Necessary to allow dropping
});
dropZone.addEventListener('drop', async (event) => {
event.preventDefault();
for (const item of event.dataTransfer.items) {
if (item.kind === 'file') {
const handle = await item.getAsFileSystemHandle();
if (handle.kind === 'directory') {
console.log(`Directory dropped: ${handle.name}`);
// Process directory handle
} else {
console.log(`File dropped: ${handle.name}`);
// Process file handle
}
}
}
});
การประยุกต์ใช้งานจริง
ความเป็นไปได้ที่ API นี้เปิดให้มีมากมายและตอบสนองต่อผู้ชมทั่วโลกทั้งครีเอเตอร์และมืออาชีพ:
- IDE และโปรแกรมแก้ไขโค้ดบนเว็บ: เครื่องมืออย่าง VS Code for the Web (vscode.dev) สามารถเปิดโฟลเดอร์โปรเจกต์ในเครื่องได้แล้ว ทำให้นักพัฒนาสามารถแก้ไข สร้าง และจัดการ codebase ทั้งหมดของพวกเขาได้โดยตรงในเบราว์เซอร์
- เครื่องมือสร้างสรรค์: โปรแกรมแก้ไขรูปภาพ วิดีโอ และเสียงสามารถโหลดไฟล์มีเดียขนาดใหญ่ได้โดยตรงจากฮาร์ดไดรฟ์ของผู้ใช้ ทำการแก้ไขที่ซับซ้อน และบันทึกผลลัพธ์โดยไม่ต้องผ่านกระบวนการอัปโหลดและดาวน์โหลดจากเซิร์ฟเวอร์ที่ช้า
- งานด้านผลิตภาพและการวิเคราะห์ข้อมูล: ผู้ใช้ทางธุรกิจสามารถเปิดไฟล์ CSV หรือ JSON ขนาดใหญ่ในเครื่องมือแสดงข้อมูลบนเว็บ วิเคราะห์ข้อมูล และบันทึกรายงานได้ โดยที่ข้อมูลไม่เคยออกจากเครื่องของพวกเขาเลย ซึ่งยอดเยี่ยมสำหรับความเป็นส่วนตัวและประสิทธิภาพ
- เกม: เกมบนเว็บสามารถอนุญาตให้ผู้ใช้จัดการเกมที่บันทึกไว้หรือติดตั้งม็อดได้โดยการให้สิทธิ์เข้าถึงโฟลเดอร์เกมที่ระบุ
ข้อควรพิจารณาและแนวทางปฏิบัติที่ดีที่สุด
พลังที่ยิ่งใหญ่มาพร้อมกับความรับผิดชอบที่ยิ่งใหญ่ นี่คือข้อควรพิจารณาที่สำคัญสำหรับนักพัฒนาที่ใช้ API นี้
เน้นประสบการณ์ผู้ใช้ (UX)
- ความชัดเจนเป็นสิ่งสำคัญ: ผูกการเรียก API กับการกระทำของผู้ใช้ที่ชัดเจนและเจาะจงเสมอ เช่น ปุ่มที่มีป้ายกำกับว่า 'เปิดไฟล์' หรือ 'บันทึกการเปลี่ยนแปลง' อย่าทำให้ผู้ใช้ประหลาดใจด้วยตัวเลือกไฟล์
- ให้ข้อเสนอแนะ: ใช้องค์ประกอบ UI เพื่อแจ้งให้ผู้ใช้ทราบเกี่ยวกับสถานะของการดำเนินการ (เช่น 'กำลังบันทึก...', 'บันทึกไฟล์สำเร็จ', 'การอนุญาตถูกปฏิเสธ')
- มีทางเลือกสำรองที่เหมาะสม: เนื่องจาก API ยังไม่ได้รับการสนับสนุนอย่างแพร่หลาย ควรมีกลไกสำรองโดยใช้วิธีการดาวน์โหลดด้วย
<input type="file">และ anchor แบบดั้งเดิมสำหรับเบราว์เซอร์รุ่นเก่าเสมอ
ประสิทธิภาพ
API นี้ถูกออกแบบมาเพื่อประสิทธิภาพ โดยการกำจัดความจำเป็นในการอัปโหลดและดาวน์โหลดจากเซิร์ฟเวอร์ แอปพลิเคชันสามารถทำงานได้เร็วขึ้นอย่างมาก โดยเฉพาะเมื่อต้องจัดการกับไฟล์ขนาดใหญ่ เนื่องจากการดำเนินการทั้งหมดเป็นแบบอะซิงโครนัส มันจะไม่บล็อกเธรดหลักของเบราว์เซอร์ ทำให้ UI ของคุณตอบสนองได้ดีอยู่เสมอ
ข้อจำกัดและความเข้ากันได้ของเบราว์เซอร์
ข้อพิจารณาที่ใหญ่ที่สุดคือการสนับสนุนของเบราว์เซอร์ ณ ปลายปี 2023 API ได้รับการสนับสนุนอย่างเต็มที่ในเบราว์เซอร์ที่ใช้ Chromium เช่น Google Chrome, Microsoft Edge และ Opera การสนับสนุนใน Firefox อยู่ระหว่างการพัฒนาโดยต้องเปิดใช้งานผ่าน flag และ Safari ยังไม่ได้ให้คำมั่นว่าจะนำไปใช้ สำหรับผู้ชมทั่วโลก นี่หมายความว่าคุณไม่สามารถพึ่งพา API นี้เป็นวิธี *เดียว* ในการจัดการไฟล์ได้ ตรวจสอบแหล่งข้อมูลที่เชื่อถือได้เช่น CanIUse.com เสมอสำหรับข้อมูลความเข้ากันได้ล่าสุด
บทสรุป: ยุคใหม่สำหรับเว็บแอปพลิเคชัน
File System Access API แสดงถึงการก้าวกระโดดครั้งสำคัญสำหรับแพลตฟอร์มเว็บ มันแก้ไขช่องว่างด้านฟังก์ชันการทำงานที่สำคัญที่สุดอย่างหนึ่งระหว่างเว็บและแอปพลิเคชันเนทีฟโดยตรง ทำให้นักพัฒนาสามารถสร้างเครื่องมือประเภทใหม่ที่ทรงพลัง มีประสิทธิภาพ และใช้งานง่ายซึ่งทำงานทั้งหมดในเบราว์เซอร์
ด้วยการให้สะพานเชื่อมที่ปลอดภัยและควบคุมโดยผู้ใช้ไปยังระบบไฟล์ในเครื่อง มันช่วยเพิ่มความสามารถของแอปพลิเคชัน ปรับปรุงประสิทธิภาพโดยลดการพึ่งพาเซิร์ฟเวอร์ และปรับปรุงขั้นตอนการทำงานสำหรับผู้ใช้ทั่วโลก ในขณะที่เราต้องคำนึงถึงความเข้ากันได้ของเบราว์เซอร์และใช้ทางเลือกสำรองที่เหมาะสม เส้นทางข้างหน้าก็ชัดเจน เว็บกำลังพัฒนาจากแพลตฟอร์มสำหรับการบริโภคเนื้อหาไปสู่แพลตฟอร์มที่สมบูรณ์สำหรับการสร้างสรรค์ เราขอแนะนำให้คุณสำรวจ File System Access API ทดลองกับความสามารถของมัน และเริ่มสร้างเว็บแอปพลิเคชันรุ่นต่อไปตั้งแต่วันนี้